import re
import traceback
from .app import bot
from .session import CommandSession, RequestSession, NoticeSession, SysSession
from .exceptions import SessionFinishException
from .config import config
from .util import highlight_print, base64_decode


def parse_invoke(client, server, info):
    invoke_key_unknow = info.get('invoke_key')
    invoke_key_verify = config.get('invoke_key')
    if not invoke_key_verify:
        return bot.server.send_message(client, '请设置invoke_key')
    if invoke_key_unknow != invoke_key_verify:
        ret = bot.jsonify({'statue': 'error', 'info': '请提供正确的 invoke_key'})
        return bot.server.send_message(client, ret)

    g = {
        'result': '你没给我赋值, 那我就只能给你这个返回值咯'
    }
    try:
        exec(info['code'], g)
        ret = bot.jsonify({'statue': 'success', 'info': str(g['result'])})
    except Exception as e:
        print('↓' * 50)
        print(e)
        print('↑' * 50)
        ret = bot.jsonify({'statue': 'error', 'info': str(e)})

    try:
        bot.server.send_message(client, ret)
    except Exception as e:
        print(e)


def parse(info):
    event = info['event']
    if 'json_msg' in info:
        try:
            info['json_msg_decode'] = base64_decode(info['json_msg'])
        except Exception as e:
            print(e)

    if event in ['friend_msg', 'group_msg']:
        solve_command(info)
    elif event in ['group_member_add', 'group_member_decrease', 'friend_verify']:
        solve_request(event, info)
    elif event in ['send_out_msg', 'received_transfer', 'scan_cash_money', 'contacts_change', 'sys_msg']:
        solve_notice(event, info)
    elif event in ['init', 'enable', 'login', 'stop']:
        solve_sys(event, info)


def solve_command(info):
    session = CommandSession(info)
    # 1/文本消息 3/图片消息 34/语音消息 42/名片消息  43/视频 47/动态表情 48/地理位置  49/分享链接  2001/红包  2002/小程序  2003/群邀请
    msg_type = int(info['type'])
    if msg_type == 1: # 文本消息
        try:
            cmd = get_cmd(info['msg'])
        except:
            return
        for cmds, func, arg_type, cmd_type in bot.cmd_route['command']:
            # regex 下的 cmds 其实是编译好的compile对象
            if (cmd_type == 'constant' and cmd in cmds) or \
                (cmd_type == 'regex' and any(pattern.findall(cmd) for pattern in cmds)):
                args, arg_str = get_args(info['msg'], cmd, arg_type) # 重名的不多，就不做缓存处理了
                session.arg_str = arg_str
                try:
                    func(args, session)
                except SessionFinishException:
                    print('Session is finished')
                except Exception as e:
                    highlight_print(f'功能错误 {cmd}: {e}')
                    highlight_print(traceback.format_exc(), fg_color=32)
    # elif msg_type == 33: # 图片消息
    #     # msg = 'image_path' # 图片地址
    #     util_solve_command(info['msg'], 'media_image')
    # elif msg_type == 34: # 语音消息
    #     # msg = 'audio_path' # 语音地址
    #     util_solve_command(info['msg'], 'media_audio')
    # elif msg_type == 43: # 视频
    #     # msg = 'video_path' # 视频地址
    #     util_solve_command(info['msg'], 'media_video')
    # elif msg_type == 48: # 地理位置
    #     # msg = {"x":"0.0000","y":"0.000","desc":"地球","title":"地球村"}
    #     util_solve_command(eval(info['msg']), 'media_location')


def solve_request(event, info):
    json_data = info['json_msg']
    session = RequestSession(info, info['json_msg'])
    for cmds, func in bot.cmd_route['request']:
        if event in cmds: func(json_data, session)


def solve_notice(event, info):
    json_data = info['json_msg']
    session = NoticeSession(info, info['json_msg'])
    for cmds, func in bot.cmd_route['notice']:
        if event in cmds: func(json_data, session)


def solve_sys(event, info):
    session = SysSession(info)
    for cmds, func in bot.cmd_route['sys_env']:
        if event in cmds: func(session)


def get_cmd(msg):
    return msg.strip().split()[0]


def get_args(msg, cmd, arg_type):
    url_sep = config.url_sep or '[&|_]+'
    arg_str = re.sub('^\s*{}\s*'.format(cmd), '', msg)
    if arg_type == 'url':
        args = dict([item.split('=', 1) for item in re.split(url_sep, arg_str)]) if arg_str else {}
    elif arg_type == 'list': # 忽略多空格
        args = re.split(f"{config.setting_bot.SEP}+", arg_str) if arg_str else []
    return args, arg_str
